"""异常处理模块."""

from collections.abc import Callable

from pydantic import JsonValue


class ApplicationException(Exception):
    """应用异常基类."""

    message: str
    """异常信息"""

    meta: dict[str, JsonValue] | None
    """异常元数据"""

    def __init__(self, message: str, meta: dict[str, JsonValue] | None = None) -> None:
        """
        初始化应用异常.

        Args:
            message (str): 异常信息
            meta (dict[str, Any], optional): 异常元数据

        """
        super().__init__()

        self.message = message
        self.meta = meta

    def add_metas(self, **kwargs: JsonValue) -> None:
        """
        添加异常元数据.

        Args:
            kwargs (JsonValue): 异常元数据

        """
        self.meta = self.meta or {}
        self.meta.update(kwargs)

    @classmethod
    def may[T](
        cls,
        func: Callable[[], T],
        meta: Callable[[], dict[str, JsonValue]] | None = None,
    ) -> T:
        """
        处理异常.

        Args:
            func (Callable[[], T]): 异常处理函数
            meta (Callable[[], dict[str, Any]], optional): 异常元数据. Defaults to None.

        Returns:
            T: 处理后的结果

        Raises:
            ApplicationException: 应用异常

        """
        try:
            return func()
        except cls as e:
            if meta is not None:
                e.add_metas(**meta())
            raise e
        except ApplicationException as e:
            ne = cls(e.message, e.meta)
            if meta is not None:
                ne.add_metas(**meta())
            raise ne from e
        except Exception as e:
            ne = ApplicationException(str(e))
            if meta is not None:
                ne.add_metas(**meta())
            raise ne from e
